﻿using BarrageGameAssistant.Core.Configs;
using BarrageGameAssistant.Core.Enums;
using BarrageGameAssistant.Core.Model;
using BarrageGameAssistant.Core.Utils;
using ImageProcess;
using BarrageGameAssistant.Core.Extensions;
using System.Drawing.Imaging;

namespace BarrageGameAssistant.UIForms
{
    public partial class FrmSceneMatchData : Form
    {
        private bool _newFlag = true; //新建标记
        private string sceneDir = string.Empty;
        private string matchImageFile = string.Empty;

        #region 基本属性
        public SceneMatchData? MatchData;

        /// <summary>
        /// 程序配置
        /// </summary>
        public Settings? Settings { get; set; }

        /// <summary>
        /// 游戏配置
        /// </summary>
        public GameProject? CurrentGame { get; set; }

        /// <summary>
        /// 场景信息
        /// </summary>
        public Scene? Scene { get; set; }

        public int PreProcessingMode { get; set; }
        #endregion

        public Rectangle Box;

        private string _sceneImageFile = string.Empty;

        public FrmSceneMatchData()
        {
            InitializeComponent();
        }

        private System.Drawing.Image GetImage(string path)
        {
            using FileStream fs = new(path, FileMode.Open, FileAccess.Read);
            System.Drawing.Image result = System.Drawing.Image.FromStream(fs);
            fs.Close();
            return result;
        }

        private void FrmSceneMatchData_Load(object sender, EventArgs e)
        {
            

            this.cbbMatchType.SelectedIndex = 0;
            this.cbbIncludeLogic.SelectedIndex = 0;
            this.cbbOcrMatchType.SelectedIndex = 0;
            this.cbbOcrMatchType.Enabled = false;
            this.txtOcr.Enabled = false;
            this.btnOcr.Enabled = false;

            sceneDir = Scene.CurrentDirectory(CurrentGame);

            if (MatchData == null)
            {
                _newFlag = true;

                this.cbbPreProcessingMode.SelectedIndex = PreProcessingMode;

                MatchData = new SceneMatchData((IdentifyMatchType)cbbMatchType.SelectedIndex, Box);
                matchImageFile = Path.Combine(sceneDir, $"{MatchData.Id}.png");
                this.Text = "新建场景识别项";

                _sceneImageFile = Path.Combine(sceneDir, $"{Scene?.Id}.png");
                using var matchImg = ImageProcess.ImageHelper.Crop(_sceneImageFile, MatchData.Bounds);
                matchImg?.Save(matchImageFile, ImageFormat.Png);
                this.pictureBox1.Image = GetImage(matchImageFile);
            }
            else
            {
                _newFlag = false;
                matchImageFile = Path.Combine(sceneDir, $"{MatchData.Id}.png");
                this.Text = "编辑场景识别项";
                this.cbbPreProcessingMode.SelectedIndex = (int)MatchData.PreProcessingMode;

                this.cbbMatchType.SelectedIndex = (int)MatchData.MatchType;
                this.cbbIncludeLogic.SelectedIndex = MatchData.IncludeLogic;
                this.nudThreshold.Value = Convert.ToDecimal(MatchData.Threshold);
                if (MatchData.MatchType == IdentifyMatchType.OCR)
                {
                    this.txtOcr.Text = MatchData.OcrText;
                    this.cbbOcrMatchType.SelectedIndex = (int)MatchData.OcrMatchType;
                    this.cbbOcrMatchType.Enabled = true;
                    this.txtOcr.Enabled = true;
                    this.btnOcr.Enabled = true;
                }
            }


        }

        private void btnOcr_Click(object sender, EventArgs e)
        {
            try
            {
                using OcrHelper ocr = new();
                ocr.Threshold = Convert.ToSingle(this.nudThreshold.Value);

                float score;
                string result = ocr.GetText(matchImageFile, out score);

                if (cbbOcrMatchType.SelectedIndex == 1)
                    this.txtOcr.Text = RegexUtils.GetChinese(result);
                else if (cbbOcrMatchType.SelectedIndex == 2)
                    this.txtOcr.Text = RegexUtils.GetDigit(result);
                else if (cbbOcrMatchType.SelectedIndex == 3)
                    this.txtOcr.Text = RegexUtils.GetEnglish(result);
                else
                    this.txtOcr.Text = result;

                string tmp = string.Empty;
                if(score >= Convert.ToSingle(this.nudThreshold.Value)) 
                {
                    if (this.cbbIncludeLogic.SelectedIndex == 0)
                        tmp = $"得分[{score:F2}] >= 阈值[{this.nudThreshold.Value:F2}],条件成立";
                    else
                        tmp = $"得分[{score:F2}] >= 阈值[{this.nudThreshold.Value:F2}],条件不成立";
                }
                else
                {
                    if (this.cbbIncludeLogic.SelectedIndex == 0)
                        tmp = $"得分[{score:F2}] <= 阈值[{this.nudThreshold.Value:F2}],条件不成立";
                    else
                        tmp = $"得分[{score:F2}] <= 阈值[{this.nudThreshold.Value:F2}],条件成立";
                }
                var sbtj = this.cbbIncludeLogic.SelectedIndex == 0 ? "包含" : "不包含";

                MessageBox.Show(this, $"识别内容: {result}{Environment.NewLine}识别条件: {sbtj}{Environment.NewLine}识别得分: {score:F2}{Environment.NewLine}识别结论: {tmp}", "识别结果", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception)
            {
                MessageBox.Show(this, $"识别错误.", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            if (this.cbbMatchType.SelectedIndex == 2 && string.IsNullOrEmpty(this.txtOcr.Text))
            {
                MessageBox.Show(this, $"识别错误.", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.txtOcr.Focus();
                return;
            }

            if (MatchData == null)
            {
                //添加
                MatchData = new SceneMatchData((IdentifyMatchType)cbbMatchType.SelectedIndex, Box)
                {
                    PreProcessingMode = (PreProcessingModeType)this.cbbPreProcessingMode.SelectedIndex,
                    IncludeLogic = cbbIncludeLogic.SelectedIndex,
                    Threshold = Convert.ToDouble(this.nudThreshold.Value),
                    OcrMatchType = (OcrMatchType)cbbOcrMatchType.SelectedIndex,
                    OcrText = this.txtOcr.Text.Trim()
                };
            }
            else
            {
                //编辑
                MatchData.PreProcessingMode = (PreProcessingModeType)this.cbbPreProcessingMode.SelectedIndex;
                MatchData.MatchType = (IdentifyMatchType)cbbMatchType.SelectedIndex;
                MatchData.IncludeLogic = cbbIncludeLogic.SelectedIndex;
                MatchData.Threshold = Convert.ToDouble(this.nudThreshold.Value);
                MatchData.OcrMatchType = (OcrMatchType)cbbOcrMatchType.SelectedIndex;
                MatchData.OcrText = this.txtOcr.Text.Trim();
            }

            this.DialogResult = DialogResult.OK;
        }

        #region 下拉控件选择处理事件
        private void cbbPreProcessingMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (MatchData == null) return;

            if (Settings == null) return;
            if (CurrentGame == null) return;
            if (Scene == null) return;
            switch (this.cbbPreProcessingMode.SelectedIndex)
            {
                case 1:
                    _sceneImageFile = Path.Combine(sceneDir, $"{Scene?.Id}_hsv.png");
                    break;
                case 2:
                    _sceneImageFile = Path.Combine(sceneDir, $"{Scene?.Id}_gray.png");
                    break;
                case 3:
                    _sceneImageFile = Path.Combine(sceneDir, $"{Scene?.Id}_binary.png");
                    break;
                default:
                    _sceneImageFile = Path.Combine(sceneDir, $"{Scene?.Id}.png");
                    break;
            }
            if (File.Exists(_sceneImageFile))
            {
                using var matchImg = ImageProcess.ImageHelper.Crop(_sceneImageFile, MatchData.Bounds);
                matchImg?.Save(matchImageFile, ImageFormat.Png);
                this.pictureBox1.Image = GetImage(matchImageFile);
            }
        }

        private void cbbMatchType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbbMatchType.SelectedIndex == 2)
            {
                this.cbbOcrMatchType.Enabled = true;
                this.txtOcr.Enabled = true;
                this.btnOcr.Enabled = true;
                this.btnTest.Enabled = false;
            }
            else
            {
                this.cbbOcrMatchType.Enabled = false;
                this.txtOcr.Enabled = false;
                this.btnOcr.Enabled = false;
                this.txtOcr.Text = string.Empty;
                this.btnTest.Enabled = true;
            }
        }
        #endregion
    }
}
